﻿using System.Reflection;

namespace Foundation.Core
{
    public class SelectCollectionServiceOptionsBuilder : SelectExtend
    {
        public SelectCollectionServiceOptionsBuilder(SelectCollectionStore store, SelectFilterRegistrar registrar, SelectCollectionParameterTypeValueProviderRegistrar parameterTypeValueProviderRegistrar)
        {
            Store = store;
            Registrar = registrar;
            ParameterTypeValueProviderRegistrar = parameterTypeValueProviderRegistrar;
            TypeFilter = new SelectTypeFilter(registrar);
        }

        protected internal SelectCollectionStore Store { get; }

        public SelectFilterRegistrar Registrar { get; }

        public SelectCollectionParameterTypeValueProviderRegistrar ParameterTypeValueProviderRegistrar { get; }

        public ISelectTypeFilter TypeFilter { get; }

        public bool IsEnabledListingLoadAssembly { get; set; } = true;

        protected internal List<Action<SelectCollectionServiceOptionsBuilder, Assembly>> AssemblyConfiguration = new List<Action<SelectCollectionServiceOptionsBuilder, Assembly>>();

        public SelectItemOptions AddTypeOptions(string key, Type type, SelectCategory? category = null)
        {
            var selectCategory = category.HasValue ? category.Value : (type.IsEnum ? SelectCategory.Enum : SelectCategory.Constant);
            if (Store.IsExists(key, selectCategory))
            {
                throw new ArgumentException($"{key}，{category} 在配置中已存在");
            }

            var options = new SelectItemOptions(key, selectCategory) { ItemDeclaringType = type, CacheTime = TimeSpan.FromDays(10) };

            Store.AddOptions(options);

            return options;
        }

        public void AddTypeSelectExecutor(ITypeSelectCreateExecutor executor)
        {
            Registrar.AddExecutor(executor);
        }

        public void AddTypeResultFilter(ISelectResultFilter filter)
        {
            Registrar.AddResultFilter(filter);
        }

        public void AddAssemblyCongigure(Action<SelectCollectionServiceOptionsBuilder, Assembly> configure)
        {
            if (configure != null && !AssemblyConfiguration.Contains(configure))
            {
                AssemblyConfiguration.Add(configure);
            }
        }

        public bool IsExists(string key, SelectCategory category)
        {
            return Store.IsExists(key, category);
        }

        public bool IsExists(string key, Type type)
        {
            return Store.IsExists(key, type);
        }
    }
}
